package com.link_with_health.utils;

import com.link_with_health.config.YmlProperties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.annotation.PostConstruct;
import javax.mail.*;
import javax.annotation.Resource;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import java.nio.charset.Charset;
import java.util.*;

@Component
public class EmailUtil {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());
    @Resource
    private YmlProperties ymlProperties;

    private String smtp;
    private String username;
    private String password;
    //邮件会话
    private Session session;
    //配置属性
    private Properties prop;
    //
    private String contentType;

    public EmailUtil(){
    }


    /**
     * 发送纯文本邮件
     * @param recipients 接收者
     * @param subject 主题
     * @param body 文本
     * @return 发送结果
     */
    public Boolean sendEmail(String[] recipients, String subject, String body){
        try{

            //创建邮件对象
            MimeMessage message = setMessage(recipients);
            message.setSubject(subject);
            message.setContent(body, this.contentType);

            //获取连接对象
            Transport transport = session.getTransport();
            //连接服务器
            transport.connect(this.smtp,this.username,this.password);
            //发送邮件
            transport.sendMessage(message, message.getAllRecipients());
            transport.close();
            return true;

        }catch (Exception e) {
            logger.error("[error In EmailUtil.sendEmail]",e);

        }
        return false;
    }

    /**
     * 复杂邮件
     * @param recipients 接收者
     * @param subject 主题
     * @param textContent 文本
     * @param pic 图片
     * @param appendix 附件
     * @return 返回结果
     */
    public boolean complexEmail(String[] recipients, String subject
            , String textContent, Map<String,String> pic, Map<String,String> appendix) {
        try {

            MimeMessage message = setMessage(recipients);

            //设置图片对象
            List<MimeBodyPart> imgArray = new LinkedList<>();
            for (Map.Entry<String, String> set : pic.entrySet()){
                MimeBodyPart imgPart = new MimeBodyPart();
                imgPart.setDataHandler(new DataHandler(
                        new FileDataSource(set.getValue())));
                imgPart.setContentID(set.getKey());
                imgArray.add(imgPart);
            }

            //设置附件对象
            List<MimeBodyPart> appArray = new LinkedList<>();
            for (Map.Entry<String, String> set : appendix.entrySet()){
                MimeBodyPart appPart = new MimeBodyPart();
                appPart.setDataHandler(new DataHandler(
                        new FileDataSource(set.getValue())));
                appPart.setFileName(set.getKey());
                appArray.add(appPart);
            }

            MimeBodyPart text = new MimeBodyPart();
            text.setContent(textContent,this.contentType);

            //拼装邮件主题
            MimeMultipart multipart = new MimeMultipart();

            for (MimeBodyPart mimeBodyPart : imgArray)
                multipart.addBodyPart(mimeBodyPart);
            multipart.addBodyPart(text);
            multipart.setSubType("related");//嵌入
            //邮件正文
            MimeBodyPart content = new MimeBodyPart();
            content.setContent(multipart);

            MimeMultipart body = new MimeMultipart();
            for (MimeBodyPart mimeBodyPart : appArray)
                body.addBodyPart(mimeBodyPart);
            body.addBodyPart(content);
            body.setSubType("mixed");//融合

            message.setContent(body);
            message.saveChanges();
            //获取连接对象
            Transport transport = session.getTransport();
            //连接服务器
            transport.connect(this.smtp,this.username,this.password);
            //发送邮件
            transport.sendMessage(message, message.getAllRecipients());
            transport.close();
            return true;

        } catch (Exception e) {
            logger.error("[error in EmailUtil.complexEmail]",e);
        }
        return false;
    }

    /**
     * 设置邮件的编码
     * @param charset 字符编码
     */
    public void setCharsetType(Charset charset){
        this.contentType = contentType.substring(0,18)+charset.displayName();
    }

    private MimeMessage setMessage(String[] recipients) throws MessagingException {
        //创建邮件对象
        MimeMessage message = new MimeMessage(session);
        //设置发送者
        message.setFrom(new InternetAddress(String.valueOf(prop.get("from"))));
        //设置接收者
        InternetAddress[] addresses = new InternetAddress[recipients.length];
        int index = 0;
        for(String recipient : recipients)
            addresses[index] = new InternetAddress(recipient);

        message.setRecipients(Message.RecipientType.TO
                , addresses);

        return message;
    }

    /**
     * 在无参构造函数执行后执行，配置邮件参数
     */
    @PostConstruct
    private void init(){
        this.smtp = ymlProperties.getEmailConfig().get("smtp");//"smtp.qq.com";//
        this.password = ymlProperties.getEmailConfig().get("password");//"nvasyuqdichibfee";//
        this.username = ymlProperties.getEmailConfig().get("username");//"577899820@qq.com";//
        this.prop = getProp();
        //创建邮件会话
        this.session = Session.getDefaultInstance(prop, new Authenticator() {
            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(username,password);
            }
        });

        this.contentType = "text/html;charset=UTF-8";
    }

    private Properties getProp(){
        Properties prop = new Properties();
        prop.put("from", this.username);
        prop.put("userName", this.username);
        prop.put("password", this.password);
        prop.put("mail.smtp.auth", "true");
        prop.put("mail.smtp.host", this.smtp);
        prop.put("mail.transport.protocol","smtp");
        return prop;
    }
}
